/*----------------    FILE HEADER  ------------------------------------------

This file is part of monogis.
Copyright (C) 2004-2006 by: http://sourceforge.net/projects/mgis


This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA             
---------------------------------------------------------------------------*/

/*-------------- Original license ------------------------------------------
The monoGIS GDAL driver is a collection of .NET classes written in C# that
implement the fundamental P/Invoke operations required to treat 
geo-spatial data using Frank Wamerdam's GDAL C++ library.

This collection of classes is a porting (with some additions and modifications) of
code that has been sent to the gdal-dev mailing list (gdal-dev@lists.maptools.org). 
We want especially thank to:
- Simon Perkins, for contributing his GDAL_csharp library to gdal-dev:
------ GDAL_csharp "license" ---
"This partial implementation is good enough for my needs now. If anyone 
else wants to use it, please feel free. If you want to extend it and 
send updates to me, great! The code doesn't contain any explcit licence 
headers, but Michael was suggesting an MIT licence, same as GDAL. Fine 
with me.

Cheers,

Sy"

 * ------ GDAL_csharp "license" ---
- Morton Nielsen, for contributing code and many ideas to gdal-dev:
"
Great work on the .NET wrappers. I decided to take it a step further and putting it all
in some nice classes, so you won't have to worry about pointers, disposing objects etc.
I think a lot of .NET developers would like that approach. 
I put the code example for download here:
     http://www.iter.dk/dotnet/gdal/gdal_test.zip

I added some code-comments copied from the gdal website as well, 
so you will have intellisence on most of the methods.
"
------ gdal_test "license" ----------------------------------------------------
 * ---------------------------------

Copyright (c) 2005 Morten Nielsen

Permission is hereby granted, free of charge, to any person obtaining a copy 
of this software and associated documentation files (the "Software"), to deal 
in the Software without restriction, including without limitation the rights 
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all 
copies of this Software or works derived from this Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
SOFTWARE.

------ gdal_test "license" ------------------------------------------------------


 
Copy of GDAL/OGR license:
  Copyright (c) 2000, Frank Warmerdam

Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE. 
---------------------------------------------------------------------------*/
using System;
using System.Text;
using System.Runtime.InteropServices;

namespace Gdal
{
    public class Driver
    {
        internal HandleRef hDriver;

        public Driver()
        {
            hDriver = new HandleRef(this, IntPtr.Zero);
        }

        public Driver(string name)
        {
            hDriver = new HandleRef(this, InterOp.GDALGetDriverByName(name));

            if (hDriver.Handle == IntPtr.Zero)
                throw (new ArgumentException("Driver not found"));
        }

        internal Driver(IntPtr ptrDriver)
        {
            hDriver = new HandleRef(this, ptrDriver);
        }

        /// <summary>
        /// Create a copy of a dataset.
        /// </summary>
        /// <remarks>
        /// <para>This method will attempt to create a copy of a raster dataset with the indicated filename, and in this drivers format. Band number, size, type, projection, geotransform and so forth are all to be copied from the provided template dataset.</para>
        /// <para>Note that many sequential write once formats (such as JPEG and PNG) don't implement the Create() method but do implement this CreateCopy() method. If the driver doesn't implement CreateCopy(), but does implement Create() then the default CreateCopy() mechanism built on calling Create() will be used.</para>
        /// <para>It is intended that CreateCopy() would often be used with a source dataset which is a virtual dataset allowing configuration of band types, and other information without actually duplicating raster data. This virtual dataset format hasn't yet been implemented at the time of this documentation being written.</para>
        /// </remarks>
        /// <param name="filename">Name of output file</param>
        /// <param name="srdDataset">The dataset to copy</param>
        /// <param name="strict">Insist that the copy is a "strict" copy</param>
        /// <param name="options">File construction options. See the GDAL documentation on individual
        /// drivers for details. Note that this argument is currently ignored...</param>
        public Dataset CreateCopy(string filename, Dataset srcDataset, bool strict, string[] options)
        {
            //Do a straight copy.
            Dataset dstDataset = new Dataset(InterOp.GDALCreateCopy(hDriver, filename, srcDataset.hDataset, 
                strict ? 1 : 0, new HandleRef(this, IntPtr.Zero), new HandleRef(this, IntPtr.Zero), 
                new HandleRef(this, IntPtr.Zero)));
            if (!dstDataset.IsValid)
                throw new ApplicationException("Error while creating new file " + filename + "\n" +
                    InterOp.CPLGetLastErrorMsg());
            return dstDataset;
        }

        /// <summary>
        /// Create a Dataset in the current driver's format, with the given filename, 
        /// width, height, number of bands and data type.
        /// </summary>
        /// <param name="filename">Filename to create</param>
        /// <param name="width">The width of the image</param>
        /// <param name="height">The height of the image</param>
        /// <param name="nBands">The number of bands in the image</param>
        /// <param name="type">The data type of the image</param>
        /// <param name="options">Construction options. See the GDAL documentation on individual
        /// drivers for details. Note that this argument is currently ignored...</param>
        /// <returns></returns>
        public Dataset Create(string filename, int width, int height, int nBands, DataType type, string[] options)
        {
            Dataset dstDataset = new Dataset(InterOp.GDALCreate(hDriver, filename, width, height, nBands, type,
                new HandleRef(this, IntPtr.Zero)));
            if (!dstDataset.IsValid)
                throw new ApplicationException("Error while creating new file " + filename + "\n" +
                    InterOp.CPLGetLastErrorMsg());
            return dstDataset;
        }

        /// <summary>
        /// Gets the short name of the driver
        /// </summary>
        public string ShortName
        {
            get { return InterOp.GDALGetDriverShortName(hDriver); }
        }

        /// <summary>
        /// Gets the long name of the driver
        /// </summary>
        public string LongName
        {
            get { return InterOp.GDALGetDriverLongName(hDriver); }
        }

        public override string ToString()
        {
            return ShortName + " (" + LongName + ")";
        }

        /// <summary>
        /// Fetch the number of registered drivers.
        /// </summary>
        /// <returns>the number of registered drivers.</returns>
        public static int GetDriverCount()
        {
            return InterOp.GDALGetDriverCount();
        }

        /// <summary>
        /// Fetch driver by index.
        /// </summary>
        /// <param name="i">the driver index from 0 to GetDriverCount()-1</param>
        /// <returns>GDAL Driver</returns>
        public static Driver GetDriver(int i)
        {
            return new Driver(InterOp.GDALGetDriver(i));
        }

        public static void DestroyDriverManager()
        {
            InterOp.GDALDestroyDriverManager();
        }
    }
}
